package services

import (
	"domain-system/models"
	"encoding/json"
	"errors"
	"time"

	"gorm.io/gorm"
)

// 在文件顶部添加自定义错误类型
var (
	ErrPostNotFound     = errors.New("帖子不存在")
	ErrUnauthorizedPost = errors.New("无权限修改此帖子")
	ErrUserNotFound     = errors.New("用户不存在")
	ErrCircleNotFound   = errors.New("圈子不存在")
	ErrPaymentRequired  = errors.New("需要完成支付才能发布帖子")
	ErrPaymentNotFound  = errors.New("未找到支付记录")
)

// PostService 帖子服务
type PostService struct {
	db             *gorm.DB
	paymentService *PaymentService
}

// NewPostService 创建帖子服务实例
func NewPostService(db *gorm.DB) *PostService {
	return &PostService{
		db:             db,
		paymentService: NewPaymentService(db),
	}
}

// CreatePostRequest 创建帖子请求
type CreatePostRequest struct {
	UserID        string                 `json:"user_id" binding:"required"`
	CircleID      uint                   `json:"circle_id" binding:"required"`
	Title         string                 `json:"title" binding:"required,max=200"`
	Content       string                 `json:"content" binding:"required"`
	Images        []string               `json:"images,omitempty"`
	Videos        []string               `json:"videos,omitempty"`
	TagIDs        []uint                 `json:"tag_ids,omitempty"`
	Visibility    models.VisibilityLevel `json:"visibility,omitempty"`
	Status        models.PostStatus      `json:"status,omitempty"`
	TransactionID string                 `json:"transaction_id"` // 支付交易ID - 暂时不要求必填

	LocationLatitude  float64 `json:"location_latitude,omitempty"`
	LocationLongitude float64 `json:"location_longitude,omitempty"`
	LocationAddress   string  `json:"location_address,omitempty"`
}

// PostListRequest 帖子列表请求
type PostListRequest struct {
	CircleID   *uint                   `json:"circle_id,omitempty"`
	CircleType *models.CircleType      `json:"circle_type,omitempty"`
	UserID     *string                 `json:"user_id,omitempty"`
	TagID      *uint                   `json:"tag_id,omitempty"`
	Status     *models.PostStatus      `json:"status,omitempty"`
	Visibility *models.VisibilityLevel `json:"visibility,omitempty"`
	Keyword    *string                 `json:"keyword,omitempty"`
	SortBy     string                  `json:"sort_by,omitempty"`    // created_at, like_count, view_count
	SortOrder  string                  `json:"sort_order,omitempty"` // asc, desc
	Page       int                     `json:"page,omitempty"`
	PageSize   int                     `json:"page_size,omitempty"`
}

// PostResponse 帖子响应
type PostResponse struct {
	ID                uint                   `json:"id"`
	UserID            string                 `json:"user_id"`
	User              *models.User           `json:"user,omitempty"`
	CircleID          uint                   `json:"circle_id"`
	Circle            *models.Circle         `json:"circle,omitempty"`
	Title             string                 `json:"title"`
	Content           string                 `json:"content"`
	Images            []string               `json:"images,omitempty"`
	Videos            []string               `json:"videos,omitempty"`
	Tags              []models.Tag           `json:"tags,omitempty"`
	Status            models.PostStatus      `json:"status"`
	Visibility        models.VisibilityLevel `json:"visibility"`
	ViewCount         int                    `json:"view_count"`
	LikeCount         int                    `json:"like_count"`
	CommentCount      int                    `json:"comment_count"`
	ShareCount        int                    `json:"share_count"`
	IsTop             bool                   `json:"is_top"`
	IsHot             bool                   `json:"is_hot"`
	PublishedAt       *time.Time             `json:"published_at"`
	CreatedAt         time.Time              `json:"created_at"`
	UpdatedAt         time.Time              `json:"updated_at"`
	LocationLatitude  float64                `json:"location_latitude,omitempty"`
	LocationLongitude float64                `json:"location_longitude,omitempty"`
	LocationAddress   string                 `json:"location_address,omitempty"`
}

func (s *PostService) CreatePost(req *CreatePostRequest) (*PostResponse, error) {
	// 验证支付状态 - 暂时禁用
	// if err := s.validatePayment(req.UserID, req.TransactionID); err != nil {
	// 	return nil, err
	// }

	// 验证圈子是否存在
	var circle models.Circle
	if err := s.db.First(&circle, req.CircleID).Error; err != nil {
		return nil, errors.New("圈子不存在")
	}

	// 验证用户是否存在
	var user models.User
	if err := s.db.Where("user_id = ?", req.UserID).First(&user).Error; err != nil {
		return nil, errors.New("用户不存在")
	}

	// 创建帖子
	post := &models.Post{
		UserID:     req.UserID,
		CircleID:   req.CircleID,
		Title:      req.Title,
		Content:    req.Content,
		Visibility: req.Visibility,
		Status:     req.Status,
		Images:     encodeJSONList(req.Images),
		Videos:     encodeJSONList(req.Videos),
		// 位置保存
		LocationLatitude:  req.LocationLatitude,
		LocationLongitude: req.LocationLongitude,
		LocationAddress:   req.LocationAddress,
	}

	// 设置默认值
	if post.Visibility == "" {
		post.Visibility = models.VisibilityPublic
	}
	if post.Status == "" {
		post.Status = models.PostStatusDraft
	}

	// 如果状态为已发布，设置发布时间
	if post.Status == models.PostStatusPublished {
		now := time.Now()
		post.PublishedAt = &now
	}

	// 开始事务
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 创建帖子
	if err := tx.Create(post).Error; err != nil {
		tx.Rollback()
		return nil, err
	}

	// 关联标签
	if len(req.TagIDs) > 0 {
		var tags []models.Tag
		if err := tx.Where("id IN ?", req.TagIDs).Find(&tags).Error; err != nil {
			tx.Rollback()
			return nil, err
		}
		if err := tx.Model(post).Association("Tags").Append(tags); err != nil {
			tx.Rollback()
			return nil, err
		}
	}

	// 更新圈子帖子数量
	if err := tx.Model(&circle).UpdateColumn("post_count", gorm.Expr("post_count + ?", 1)).Error; err != nil {
		tx.Rollback()
		return nil, err
	}

	tx.Commit()

	// 返回创建的帖子
	return s.GetPostByID(post.ID, req.UserID)
}

// validatePayment 验证支付状态
func (s *PostService) validatePayment(userID, transactionID string) error {
	// 查找支付记录
	var payment models.Payment
	err := s.db.Where("transaction_id = ? AND applicant_id = ?", transactionID, userID).First(&payment).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return ErrPaymentNotFound
		}
		return err
	}

	// 检查支付状态
	if payment.Status != models.PaymentStatusPaid {
		return ErrPaymentRequired
	}

	return nil
}

// GetPostByID 根据ID获取帖子
func (s *PostService) GetPostByID(postID uint, viewerID string) (*PostResponse, error) {
	var post models.Post
	query := s.db.Preload("User").Preload("Circle").Preload("Tags")

	if err := query.First(&post, postID).Error; err != nil {
		return nil, errors.New("帖子不存在")
	}

	// 检查可见性权限
	if !s.checkPostVisibility(&post, viewerID) {
		return nil, errors.New("无权限查看此帖子")
	}

	// 增加浏览次数（异步更新）
	go func() {
		s.db.Model(&post).UpdateColumn("view_count", gorm.Expr("view_count + ?", 1))
	}()

	return s.convertToPostResponse(&post), nil
}

// checkPostVisibility 检查帖子可见性
func (s *PostService) checkPostVisibility(post *models.Post, viewerID string) bool {
	// 作者本人可以查看
	if post.UserID == viewerID {
		return true
	}

	// 根据可见性级别检查
	switch post.Visibility {
	case models.VisibilityPublic:
		return true
	case models.VisibilityFriends:
		// 检查是否为好友关系（这里简化处理）
		return s.checkFriendship(post.UserID, viewerID)
	case models.VisibilityFollowers:
		// 检查是否关注了作者
		return s.checkFollowRelation(viewerID, post.UserID)
	case models.VisibilityPrivate:
		return false
	default:
		return false
	}
}

// checkFriendship 检查好友关系（简化实现）
func (s *PostService) checkFriendship(userID1, userID2 string) bool {
	// 这里可以实现具体的好友关系检查逻辑
	return true // 简化处理
}

// checkFollowRelation 检查关注关系
func (s *PostService) checkFollowRelation(followerID, followingID string) bool {
	var count int64
	s.db.Model(&models.Follow{}).Where("follower_id = ? AND following_id = ?", followerID, followingID).Count(&count)
	return count > 0
}

// convertToPostResponse 转换为响应格式
func (s *PostService) convertToPostResponse(post *models.Post) *PostResponse {
	return &PostResponse{
		ID:                post.ID,
		UserID:            post.UserID,
		User:              post.User,
		CircleID:          post.CircleID,
		Circle:            post.Circle,
		Title:             post.Title,
		Content:           post.Content,
		Images:            decodeJSONList(post.Images),
		Videos:            decodeJSONList(post.Videos),
		Tags:              post.Tags,
		Status:            post.Status,
		Visibility:        post.Visibility,
		ViewCount:         post.ViewCount,
		LikeCount:         post.LikeCount,
		CommentCount:      post.CommentCount,
		ShareCount:        post.ShareCount,
		IsTop:             post.IsTop,
		IsHot:             post.IsHot,
		PublishedAt:       post.PublishedAt,
		CreatedAt:         post.CreatedAt,
		UpdatedAt:         post.UpdatedAt,
		LocationLatitude:  post.LocationLatitude,
		LocationLongitude: post.LocationLongitude,
		LocationAddress:   post.LocationAddress,
	}
}

// UpdatePostRequest 更新帖子请求
type UpdatePostRequest struct {
	Title      *string                 `json:"title,omitempty"`
	Content    *string                 `json:"content,omitempty"`
	Images     []string                `json:"images,omitempty"`
	Videos     []string                `json:"videos,omitempty"`
	TagIDs     []uint                  `json:"tag_ids,omitempty"`
	Visibility *models.VisibilityLevel `json:"visibility,omitempty"`
	Status     *models.PostStatus      `json:"status,omitempty"`

	LocationLatitude  *float64 `json:"location_latitude,omitempty"`
	LocationLongitude *float64 `json:"location_longitude,omitempty"`
	LocationAddress   *string  `json:"location_address,omitempty"`
}

// CommentRequest 评论请求
type CommentRequest struct {
	UserID   string `json:"user_id" binding:"required"`
	PostID   uint   `json:"post_id" binding:"required"`
	ParentID *uint  `json:"parent_id,omitempty"`
	Content  string `json:"content" binding:"required"`
}

// CommentResponse 评论响应
type CommentResponse struct {
	ID         uint              `json:"id"`
	PostID     uint              `json:"post_id"`
	UserID     string            `json:"user_id"`
	User       *models.User      `json:"user,omitempty"`
	ParentID   *uint             `json:"parent_id"`
	Content    string            `json:"content"`
	LikeCount  int               `json:"like_count"`
	ReplyCount int               `json:"reply_count"`
	IsTop      bool              `json:"is_top"`
	CreatedAt  time.Time         `json:"created_at"`
	UpdatedAt  time.Time         `json:"updated_at"`
	Replies    []CommentResponse `json:"replies,omitempty"`
}

// UpdatePost 更新帖子
func (s *PostService) UpdatePost(postID uint, userID string, req *UpdatePostRequest) (*PostResponse, error) {
	// 获取帖子
	var post models.Post
	if err := s.db.First(&post, postID).Error; err != nil {
		return nil, ErrPostNotFound
	}

	// 检查权限
	if post.UserID != userID {
		return nil, ErrUnauthorizedPost
	}

	// 开始事务
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 更新字段
	updates := make(map[string]interface{})
	if req.Title != nil {
		updates["title"] = *req.Title
	}
	if req.Content != nil {
		updates["content"] = *req.Content
	}
	// 更新媒体（允许清空：传空数组则保存为 "[]"; 未传则不变）
	if req.Images != nil {
		updates["images"] = encodeJSONList(req.Images)
	}
	if req.Videos != nil {
		updates["videos"] = encodeJSONList(req.Videos)
	}
	// 更新位置（通过指针区分未传/赋值/清空）
	if req.LocationLatitude != nil {
		updates["location_latitude"] = *req.LocationLatitude
	}
	if req.LocationLongitude != nil {
		updates["location_longitude"] = *req.LocationLongitude
	}
	if req.LocationAddress != nil {
		updates["location_address"] = *req.LocationAddress
	}

	if req.Visibility != nil {
		updates["visibility"] = *req.Visibility
	}
	if req.Status != nil {
		updates["status"] = *req.Status
		// 如果状态改为已发布且之前未发布，设置发布时间
		if *req.Status == models.PostStatusPublished && post.PublishedAt == nil {
			now := time.Now()
			updates["published_at"] = &now
		}
	}

	if len(updates) > 0 {
		if err := tx.Model(&post).Updates(updates).Error; err != nil {
			tx.Rollback()
			return nil, err
		}
	}

	// 更新标签关联
	if req.TagIDs != nil {
		// 清除现有标签关联
		if err := tx.Model(&post).Association("Tags").Clear(); err != nil {
			tx.Rollback()
			return nil, err
		}
		// 添加新标签关联
		if len(req.TagIDs) > 0 {
			var tags []models.Tag
			if err := tx.Where("id IN ?", req.TagIDs).Find(&tags).Error; err != nil {
				tx.Rollback()
				return nil, err
			}
			if err := tx.Model(&post).Association("Tags").Append(tags); err != nil {
				tx.Rollback()
				return nil, err
			}
		}
	}

	tx.Commit()

	// 返回更新后的帖子
	return s.GetPostByID(postID, userID)
}

// DeletePost 删除帖子
func (s *PostService) DeletePost(postID uint, userID string) error {
	// 获取帖子
	var post models.Post
	if err := s.db.First(&post, postID).Error; err != nil {
		return errors.New("帖子不存在")
	}

	// 检查权限
	if post.UserID != userID {
		return errors.New("无权限删除此帖子")
	}

	// 开始事务
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 软删除帖子
	if err := tx.Delete(&post).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 更新圈子帖子数量
	if err := tx.Model(&models.Circle{}).Where("id = ?", post.CircleID).UpdateColumn("post_count", gorm.Expr("post_count - ?", 1)).Error; err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()
	return nil
}

// LikePost 点赞帖子
func (s *PostService) LikePost(postID uint, userID string) error {
	// 检查帖子是否存在
	var post models.Post
	if err := s.db.First(&post, postID).Error; err != nil {
		return errors.New("帖子不存在")
	}

	// 检查是否已经点赞
	var existingLike models.Like
	if err := s.db.Where("user_id = ? AND post_id = ?", userID, postID).First(&existingLike).Error; err == nil {
		return errors.New("已经点赞过了")
	}

	// 开始事务
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 创建点赞记录
	like := &models.Like{
		UserID: userID,
		PostID: &postID,
	}
	if err := tx.Create(like).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 更新帖子点赞数
	if err := tx.Model(&post).UpdateColumn("like_count", gorm.Expr("like_count + ?", 1)).Error; err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()
	return nil
}

// UnlikePost 取消点赞帖子
func (s *PostService) UnlikePost(postID uint, userID string) error {
	// 检查帖子是否存在
	var post models.Post
	if err := s.db.First(&post, postID).Error; err != nil {
		return errors.New("帖子不存在")
	}

	// 查找点赞记录
	var like models.Like
	if err := s.db.Where("user_id = ? AND post_id = ?", userID, postID).First(&like).Error; err != nil {
		return errors.New("未找到点赞记录")
	}

	// 开始事务
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 删除点赞记录
	if err := tx.Delete(&like).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 更新帖子点赞数
	if err := tx.Model(&post).UpdateColumn("like_count", gorm.Expr("like_count - ?", 1)).Error; err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()
	return nil
}

// GetPostComments 获取帖子评论列表
func (s *PostService) GetPostComments(postID uint, page, pageSize int) ([]CommentResponse, int64, error) {
	// 检查帖子是否存在
	var post models.Post
	if err := s.db.First(&post, postID).Error; err != nil {
		return nil, 0, errors.New("帖子不存在")
	}

	// 计算总数
	var total int64
	s.db.Model(&models.Comment{}).Where("post_id = ? AND parent_id IS NULL", postID).Count(&total)

	// 查询评论
	var comments []models.Comment
	offset := (page - 1) * pageSize
	query := s.db.Where("post_id = ? AND parent_id IS NULL", postID).
		Preload("User").
		Preload("Replies", func(db *gorm.DB) *gorm.DB {
			return db.Preload("User").Order("created_at ASC")
		}).
		Order("created_at DESC").
		Offset(offset).Limit(pageSize)

	if err := query.Find(&comments).Error; err != nil {
		return nil, 0, err
	}

	// 转换为响应格式
	var responses []CommentResponse
	for _, comment := range comments {
		response := s.convertToCommentResponse(&comment)
		responses = append(responses, *response)
	}

	return responses, total, nil
}

// CreateComment 创建评论
func (s *PostService) CreateComment(req *CommentRequest) (*CommentResponse, error) {
	// 检查帖子是否存在
	var post models.Post
	if err := s.db.First(&post, req.PostID).Error; err != nil {
		return nil, errors.New("帖子不存在")
	}

	// 检查用户是否存在
	var user models.User
	if err := s.db.Where("user_id = ?", req.UserID).First(&user).Error; err != nil {
		return nil, errors.New("用户不存在")
	}

	// 如果是回复，检查父评论是否存在
	if req.ParentID != nil {
		var parentComment models.Comment
		if err := s.db.Where("id = ? AND post_id = ?", *req.ParentID, req.PostID).First(&parentComment).Error; err != nil {
			return nil, errors.New("父评论不存在")
		}
	}

	// 开始事务
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 创建评论
	comment := &models.Comment{
		PostID:   req.PostID,
		UserID:   req.UserID,
		ParentID: req.ParentID,
		Content:  req.Content,
	}

	if err := tx.Create(comment).Error; err != nil {
		tx.Rollback()
		return nil, err
	}

	// 更新帖子评论数
	if err := tx.Model(&post).UpdateColumn("comment_count", gorm.Expr("comment_count + ?", 1)).Error; err != nil {
		tx.Rollback()
		return nil, err
	}

	// 如果是回复，更新父评论的回复数
	if req.ParentID != nil {
		if err := tx.Model(&models.Comment{}).Where("id = ?", *req.ParentID).UpdateColumn("reply_count", gorm.Expr("reply_count + ?", 1)).Error; err != nil {
			tx.Rollback()
			return nil, err
		}
	}

	tx.Commit()

	// 返回创建的评论
	var createdComment models.Comment
	if err := s.db.Preload("User").First(&createdComment, comment.ID).Error; err != nil {
		return nil, err
	}

	return s.convertToCommentResponse(&createdComment), nil
}

// GetPostList 获取帖子列表
func (s *PostService) GetPostList(req *PostListRequest, viewerID string) ([]PostResponse, int64, error) {
	// 构建查询
	query := s.db.Model(&models.Post{}).Preload("User").Preload("Circle").Preload("Tags")

	// 添加过滤条件
	if req.CircleID != nil {
		query = query.Where("circle_id = ?", *req.CircleID)
	}
	if req.UserID != nil {
		query = query.Where("user_id = ?", *req.UserID)
	}
	if req.Status != nil {
		query = query.Where("status = ?", *req.Status)
	}
	if req.Visibility != nil {
		query = query.Where("visibility = ?", *req.Visibility)
	}
	if req.Keyword != nil {
		query = query.Where("title LIKE ? OR content LIKE ?", "%"+*req.Keyword+"%", "%"+*req.Keyword+"%")
	}

	// 计算总数
	var total int64
	query.Count(&total)

	// 排序
	sortBy := "created_at"
	if req.SortBy != "" {
		sortBy = req.SortBy
	}
	sortOrder := "DESC"
	if req.SortOrder == "asc" {
		sortOrder = "ASC"
	}
	query = query.Order(sortBy + " " + sortOrder)

	// 分页
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 {
		req.PageSize = 20
	}
	offset := (req.Page - 1) * req.PageSize
	query = query.Offset(offset).Limit(req.PageSize)

	// 执行查询
	var posts []models.Post
	if err := query.Find(&posts).Error; err != nil {
		return nil, 0, err
	}

	// 转换为响应格式并过滤可见性
	var responses []PostResponse
	for _, post := range posts {
		if s.checkPostVisibility(&post, viewerID) {
			response := s.convertToPostResponse(&post)
			responses = append(responses, *response)
		}
	}

	return responses, total, nil
}

// convertToCommentResponse 转换评论为响应格式
func (s *PostService) convertToCommentResponse(comment *models.Comment) *CommentResponse {
	response := &CommentResponse{
		ID:         comment.ID,
		PostID:     comment.PostID,
		UserID:     comment.UserID,
		User:       comment.User,
		ParentID:   comment.ParentID,
		Content:    comment.Content,
		LikeCount:  comment.LikeCount,
		ReplyCount: comment.ReplyCount,
		IsTop:      comment.IsTop,
		CreatedAt:  comment.CreatedAt,
		UpdatedAt:  comment.UpdatedAt,
	}

	// 转换回复
	for _, reply := range comment.Replies {
		replyResponse := s.convertToCommentResponse(&reply)
		response.Replies = append(response.Replies, *replyResponse)
	}

	return response
}

func encodeJSONList(list []string) string {
	if list == nil {
		return "" // 未提供时保持空（不覆盖旧值）
	}
	b, _ := json.Marshal(list)
	return string(b)
}

func decodeJSONList(s string) []string {
	if s == "" {
		return []string{}
	}
	var out []string
	if err := json.Unmarshal([]byte(s), &out); err != nil {
		return []string{}
	}
	return out
}
